#ifndef SWFInputStream_H_
#define SWFInputStream_H_

#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <zlib.h>

#include "type.h"
#include "SWFHeader.h"
#include "Tag.h"
#include "Rect.h"
#include "ShowFrame.h"
#include "PlaceObject2.h"
#include "SetBackgroundColor.h"
#include "DefineText2.h"
#include "DefineFont2.h"
#include "DefineShape.h"
#include "DefineShape3.h"
#include "DefineBitsLossless.h"
#include "CSMTextSettings.h"
#include "RGB.h"
#include "RGBA.h"
#include "swf.h"
#include "Matrix.h"
#include "FillStyleArray.h"
#include "StyleChangeRecord.h"
#include "FileAttributes.h"
#include "Metadata.h"
#include "DefineEditText.h"
#include "DoABC.h"
#include "StringInfo.h"
#include "NameSpace.h"
#include "NamespaceSet.h"
#include "MultinameInfo.h"
#include "Multiname.h"
#include "MultinameL.h"
#include "QName.h"
#include "MethodInfo.h"
#include "OptionInfo.h"
#include "Instance.h"
#include "ClassInfo.h"
#include "ScriptInfo.h"
#include "MethodBody.h"

#define throw cerr<<"\nThrowS "<<__FILE__<<" "<<__LINE__<<endl,exit(1)
//throw

using namespace std;
namespace swfstream {

class SWFInputStream {
public:
	void get(FileAttributes*& r) {
		r = new FileAttributes;
		get(r->header);
		resetBits();
		getBitsU(1);
		r->useDirectBlit = getBitsU(1);
		r->useGpu = getBitsU(1);
		r->hasMetaData = getBitsU(1);
		r->actionScript3 = getBitsU(1);
		getBitsU(2);
		r->useNetwork = getBitsU(1);
		getBitsU(24);
	}
	void get(SWFHeader*& r) {
		resetBits();
		r = new SWFHeader;
		r->signature = get();
		r->signature2 = get();
		r->signature3 = get();
		if (((r->signature != 'C') && (r->signature != 'F'))
				|| (r->signature2 != 'W') || (r->signature3 != 'S')) {
			std::cerr << "not a swf file\n";
			exit(1);
		}
		if (r->signature == 'C') {
			r->isCompressed = true;
		} else if (r->signature == 'F') {
			r->isCompressed = false;
		}
		r->version = get();
		get((char*) &r->file_length, 4);
		if (r->isCompressed) {
			size_t size = 3000000;
			size_t bufsize = 3000000;
			unsigned char* from = (unsigned char*) calloc(1, size);
			unsigned char* to = (unsigned char*) calloc(1, bufsize);
			size_t n = 0;
			unsigned char*p = from;
			int lasterror = -11;
			while (n < size) {
				if (n % 30000 == 0) {
					cerr << "n=" << n << endl;
				}
				*p = get(); //is->get();
				n++;
				p++;
				uLong destLen = bufsize;
//				int r = uncompress(to, &destLen, from, n);
				//			if(r!=lasterror){
				//			cerr<<r<<endl;
				//		lasterror=r;
				//}
				if (is->eof()) {
					cerr << "eof" << endl;
					break;
				}
			}
			uLong destLen = bufsize;
			int fr = uncompress(to, &destLen, from, n);
			cerr << fr << ":" << destLen << endl;
			if (destLen + 8 != r->file_length) {
				std::cerr << "file compressed,but size may error,quit\n";
				exit(1);
			}
			this->buf_size = this->buf_bytes = destLen;
			this->buf = to;

//			std::cerr << "file compressed,not finished\n";
//			exit(1);
			/*
			 cout<<r->file_length<<endl;
			 const char* swf_name;
			 //		peek();
			 streampos l=is->tellg();
			 cout<<l<<endl;
			 //				cout<<ifstream::end<<endl;
			 is->seekg(0,ifstream::end);
			 l=is->tellg()-l;
			 cout<<l<<endl;
			 char* tmp=new char[l];
			 peek(tmp,l);
			 delete buf;
			 buf_size=l*20;
			 uLong size_u=buf_size;
			 buf=new byte[buf_size];
			 cout<<"!!!"<<size_u<<endl;
			 int ur=uncompress(buf,&size_u,(Bytef*)tmp,l);
			 cout<<"!!!r="<<ur<<endl;
			 cout<<"!!!"<<size_u<<endl;
			 //				cout<<"!!!"<<size;

			 //				byte *z=new byte[size];
			 //				uLong size_u=size*100;
			 //				byte* u=new byte[size_u];
			 //				int ru=uncompress(u,&size_u,z,size);


			 delete tmp;
			 */
		}
		get(r->frame_size);
		uint16 tmp;
		get((char*) &tmp, 2);
		r->frame_rate = tmp;
		get((char*) &tmp, 2);
		r->frame_count = tmp;
	}
	void get(PlaceObject2*& r) {
		//cerr<<"PlaceObject2\n";
		//throw;
		r = new PlaceObject2;
		get(r->header);
		byte tmp = get();
		r->PlaceFlagHasClipActions = ((tmp & 0x80) != 0);
		r->PlaceFlagHasClipDepth = ((tmp & 0x40) != 0);
		r->PlaceFlagHasName = ((tmp & 0x20) != 0);
		r->PlaceFlagHasRatio = ((tmp & 0x10) != 0);
		r->PlaceFlagHasColorTransform = ((tmp & 0x08) != 0);
		r->PlaceFlagHasMatrix = ((tmp & 0x04) != 0);
		r->PlaceFlagHasCharacter = ((tmp & 0x02) != 0);
		r->PlaceFlagMove = ((tmp & 0x01) != 0);
		get((char*) &r->depth, 2);
		if (r->PlaceFlagHasCharacter) {
			get((char*) &r->characterId, 2);
		}
		if (r->PlaceFlagHasMatrix) {
			get(r->matrix);
		}
		if (r->PlaceFlagHasColorTransform) {
			cerr << "not finished\n";
			exit(1);
		}
		if (r->PlaceFlagHasRatio) {
			get((char*) &r->ratio, 2);
		}
		if (r->PlaceFlagHasName) {
			cerr << "not finished\n";
			exit(1);
		}
		if (r->PlaceFlagHasClipDepth) {
			get((char*) &r->ClipDepth, 2);
		}
		if (r->PlaceFlagHasClipActions) {
			cerr << "not finished\n";
			exit(1);
		}
	}
	void get(Matrix*& r) {
		//		cerr<<"Matrix\n";
		//	throw;
		r = new Matrix;
		//Bits bits;
		resetBits();
		r->HasScale = getBitsU(1);
		if (r->HasScale == 1) {
			r->NScaleBits = getBitsU(5);
			r->ScaleX = getBitsS(r->NScaleBits) / (float) 0x10000; //notice:as float
			r->ScaleY = getBitsS(r->NScaleBits) / (float) 0x10000; //notice:as float
			//r->ScaleX=bits.read_u(r->NScaleBits,f);//notice:as float
			//ScaleX If HasScale = 1, FB[NScaleBits] x scale value
			//r->ScaleY=bits.read_u(r->NScaleBits,f);//notice:as float
			//ScaleY If HasScale = 1,  FB[NScaleBits] y scale value
		}
		r->HasRotate = getBitsU(1);
		if (r->HasRotate == 1) {
			r->NRotateBits = getBitsU(5);
			r->RotateSkew0 = getBitsS(r->NRotateBits) / (float) 0x10000; //notice:as float
			r->RotateSkew1 = getBitsS(r->NRotateBits) / (float) 0x10000; //notice:as float

			//fprintf(stderr,"unfinished:has_scale\n");
			//exit(1);
			//uint8 NRotateBits;///< If HasRotate = 1,  UB[5] Bits in each rotate value field
			//RotateSkew0 If HasRotate = 1,  FB[NRotateBits]First rotate and skew value
			//RotateSkew1 If HasRotate = 1,  FB[NRotateBits]Second rotate and skew value
		}
		r->NTranslateBits = getBitsU(5);
		r->TranslateX = getBitsS(r->NTranslateBits);
		r->TranslateY = getBitsS(r->NTranslateBits);
		//r->size=bits.byte_num();

	}
	void get(LineStyle*& r, uint shape_version) {
		//cerr<<"LineStyle\n";
		//throw;
		r = new LineStyle;
		uint16 tmp;
		get((char*) &tmp, 2);
		r->width = tmp;
		if ((shape_version == 1) || (shape_version == 2)) {
			get((RGB*&) r->color);
		} else if (shape_version == 3) {
			get((RGBA*&) r->color);
		} else {
			cerr << "in line_style::from_file:not finished";
			exit(1);
		}

	}
	void get(FillStyle*& r, uint shape_version) {
		//cerr<<"FillStyle\n";
		//			throw;
		r = new FillStyle;
		r->FillStyleType = get();
		//fprintf(stderr,"FillStyleType=0x%X\n",r->FillStyleType);
		if (r->FillStyleType == 0) {
			if ((shape_version == 1) || (shape_version == 2)) {
				//r->color=RGB::from_file(f);
				get((RGB*&) r->color);
			} else if (shape_version == 3) {
				//r->color=RGBA::from_file(f);
				get((RGBA*&) r->color);
			} else {
				fprintf(stderr, "in fill_style::from_file,not finished\n");
				exit(1);
			}
		}
		if ((r->FillStyleType == 0x10) || (r->FillStyleType == 0x12)
				|| (r->FillStyleType == 0x13)) {
			get(r->GradientMatrix); //=Matrix::from_file(f);
		}
		if ((r->FillStyleType == 0x10) || (r->FillStyleType == 0x12)
				|| (r->FillStyleType == 0x13)) {
			cerr << "in fill_style::from_file,type=0x" << hex
					<< (uint) r->FillStyleType << dec << ",not finished\n";
			exit(1);
		}
		if ((r->FillStyleType == 0x40) || (r->FillStyleType == 0x41)
				|| (r->FillStyleType == 0x42) || (r->FillStyleType == 0x43)) {
			uint16 tmp;
			get((char*) &tmp, 2);
			r->BitmapId = tmp;
			//(r->BitmapMatrix=Matrix::from_file(f))->print();
			get(r->BitmapMatrix);
		}
	}
	void get(LineStyleArray*& r, uint shape_version) {
		//cerr<<"LineStyleArray\n";
		//			throw;
		uint size;
		r = new LineStyleArray;
		//r->FillStyleCount=getc(f);
		//size=r->FillStyleCount;
		uint tmp = get();
		r->LineStyleCount = tmp;
		//printf("LINESTYLEARRAY.size1=%u\n",(uint)tmp);
		if (tmp == 0xff) {
			//exit(16);
			uint16 tmp2;
			get((char*) &tmp2, 2);
			size = tmp2;
			r->LineStyleCountExtended = size;
			//printf("LINESTYLEARRAY.size2=%u\n",size);
		} else {
			size = tmp;
		}
		for (uint i = 0; i < size; i++) {
			if (shape_version <= 3) {
				LineStyle*tmp;
				get(tmp, shape_version);
				r->push_back(tmp);
				//r->push_back(LineStyle::from_file(f,shape_version));
			} else {
				cerr << "in line_style_array::from_file,not finished\n";
				exit(1);
			}
		}
	}
	void get(FillStyleArray*& r, uint shape_version) {
		//cerr<<"FillStyleArray\n";
		r = new FillStyleArray;
		uint size;
		size = get();
		if ((size == 0xff) && ((shape_version == 2) || (shape_version == 3))) {
			//exit(16);
			//fread(&r->FillStyleCountExtended,2,1,f);
			//size=r->FillStyleCountExtended;
			uint16 tmp;
			get((char*) &tmp, 2);
			size = tmp;
			//printf("FILLSTYLEARRAY.size2=%u\n",size);
		}
		for (uint i = 0; i < size; i++) {
			//				r->push_back(FillStyle::from_file(f,shape_version));
			FillStyle * tmp;
			get(tmp, shape_version);
			r->push_back(tmp);
		}
		//throw;
	}
	void get(CSMTextSettings*& r) {
		//cerr<<"CSMTextSettings\n";
		r = new CSMTextSettings;
		get(r->header);
		char* tmp = new char[r->header->length];
		get(tmp, r->header->length);
		//delete tmp;
		//throw;
	}
	void get(DefineBitsLossless*& r) {
		//cerr<<"DefineBitsLossless\n";
		throw;
	}
	void get(DefineFont2*& r) {
		//cerr<<"DefineFont2\n";
		//throw;

		int size_read = 0;
		r = new DefineFont2;
		get(r->header);
		//			char buf[10000];
		//			get(buf,r->header->length);
		//			return;
		r->header->print();
		//exit(33);
		get((char*) &r->CharacterID, 2);
		size_read += 2;
		byte tmp = get();
		size_read += 1;
		r->FontFlagsHasLayout = ((tmp & 0x80) != 0);
		r->FontFlagsShiftJIS = ((tmp & 0x40) != 0);
		r->FontFlagsSmallText = ((tmp & 0x20) != 0);
		r->FontFlagsANSI = ((tmp & 0x10) != 0);
		r->FontFlagsWideOffsets = ((tmp & 0x08) != 0);
		r->FontFlagsWideCodes = ((tmp & 0x04) != 0);
		r->FontFlagsItalic = ((tmp & 0x02) != 0);
		r->FontFlagsBold = ((tmp & 0x01) != 0);
		r->LanguageCode = get();
		size_read += 1;
		//cerr<<"&&&&&&&&&&&&&&&&&&&&&&&&&"<<endl;

		r->FontNameLen = get();
		size_read += 1;

		r->FontName = new byte[r->FontNameLen];

		get((char*) r->FontName, r->FontNameLen);
		size_read += r->FontNameLen;

		get((char*) &r->NumGlyphs, 2);
		size_read += 2;

		if (r->FontFlagsWideOffsets) {
			r->OffsetTable = new uint32[r->NumGlyphs];
			get((char*) r->OffsetTable, 4 * r->NumGlyphs);
			size_read += (4 * r->NumGlyphs);
			uint32 tmp;
			get((char*) &tmp, sizeof(tmp));
			size_read += sizeof(tmp);
			r->CodeTableOffset = tmp;
		} else {
			r->OffsetTable = new uint16[r->NumGlyphs];
			get((char*) r->OffsetTable, 2 * r->NumGlyphs);
			size_read += (2 * r->NumGlyphs);
			uint16 tmp;
			get((char*) &tmp, sizeof(tmp));
			size_read += sizeof(tmp);
			r->CodeTableOffset = tmp;
		}
		//printf("CodeTableOffset:%u,",(uint)r->CodeTableOffset);
		//cerr<<r->header->length<<":::"<<size_read<<endl;
		size_t size_skip; //skip the SHAPETable
		if (r->FontFlagsWideOffsets) {
			size_skip = r->CodeTableOffset - 4 * (r->NumGlyphs + 1);
		} else {
			size_skip = r->CodeTableOffset - 2 * (r->NumGlyphs + 1);
		}
		while (size_skip--) {
			get();
			size_read += 1;
		}
		//cerr<<r->header->length<<":::"<<size_read<<endl;
		//cerr<<"&&&&&&&&&&&&&&&&&&&&&&&&&"<<endl;
		if (r->FontFlagsWideOffsets) {
			r->CodeTable = new uint16[r->NumGlyphs];
			get((char*) r->CodeTable, 2 * r->NumGlyphs);
			size_read += 2 * r->NumGlyphs;
			//FILE* tf=fopen("code.tmp","wb");
			//fwrite(r->CodeTable,2,r->NumGlyphs,tf);
			//fclose(tf);
		} else {
			//r->OffsetTable=new uint8[r->NumGlyphs];
			r->CodeTable = new uint8[r->NumGlyphs];
			get((char*) r->CodeTable, r->NumGlyphs);
			size_read += r->NumGlyphs;
		}
		//cerr<<r->header->length<<":::"<<size_read<<endl;
		//cerr<<"&&&&&&&&&&&&&&&&&&&&&&&&&"<<endl;
		if (r->FontFlagsHasLayout) {
			get((char*) &r->FontAscent, 2);
			get((char*) &r->FontDescent, 2);
			get((char*) &r->FontLeading, 2);
			r->FontAdvanceTable = new int16[r->NumGlyphs];
			get((char*) r->FontAdvanceTable, 2 * r->NumGlyphs);
			size_read += (6 + 2 * r->NumGlyphs);
			//puts("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
		}
		//cerr<<r->header->length<<":::"<<size_read<<endl;
		//cerr<<"&&&&&&&&&&&&&&&&&&&&&&&&&"<<endl;
		//skip left part of the tag
		byte tmpbuf[10000];
		//	printf("\nsizes:0x%X,0x%X\n",(uint)r.header.length,(uint)size_read);
		//	fread(tmpbuf,r.header.length-size_read,1,f);
		//printf("\nsizes:0x%X,0x%X\n",(uint)tag_size,(uint)size_read);
		//get((char*)tmpbuf,tag_size-size_read);
		//cerr<<"&&&&&&&&&&&&&&&&&&&&&&&&&"<<endl;
		//r->header->print();
		//cerr<<r->header->length<<":::"<<size_read<<endl;
		get((char*) tmpbuf, r->header->length - size_read);
		//cerr<<"&&&&&&&&&&&&&&&&&&&&&&&&&"<<endl;

	}
	void get(DefineShape*& r) {
		r = new DefineShape;
		get(r->header);
		char *tmp = new char[r->header->length];
		get(tmp, r->header->length);
		//cerr<<"DefineShape\n";
		//throw;
	}
	void get(DefineShape3*& r) {
		//cerr<<"DefineShape3\n";
		r = new DefineShape3;
		get(r->header);
		//fread(&r->shape_id,2,1,f);
		get((char*) &r->CharacterID, 2);
		//printf("define_shape3::shape_id=%u,",(uint)r->shape_id);
		get(r->shape_bounds);
		//r->shape_bounds->print();
		//throw;
		get(r->shapes, 3); //=ShapeWithStyle::from_file(f,3);
	}
	void get(std::vector<TextRecord*>*& r, bool in_define_text2, int GlyphBits,
			int AdvanceBits) {
		r = new std::vector<TextRecord*>();
		TextRecord*t;
		while (1) {
			//while((t=TextRecord::from_file(f,in_define_text2,GlyphBits,AdvanceBits))!=NULL)
			get(t, in_define_text2, GlyphBits, AdvanceBits);
			if (t == NULL) {
				break;
			}
			r->push_back(t);
		}

	}
	void get(TextRecord*& r, bool in_define_text2, int GlyphBits,
			int AdvanceBits) {
		r = new TextRecord;
		/*
		 byte tmp=get();
		 if((tmp&0xf0)!=0x80){
		 //fprintf(stderr,"Reserved must be set to 1000B\n");
		 ungetc(tmp,f);
		 r=NULL;
		 }
		 */
		byte tmp;
		peek((char*) &tmp, 1);
		if ((tmp & 0xf0) != 0x80) {
			//fprintf(stderr,"Reserved must be set to 1000B\n");
			//ungetc(tmp,f);
			r = NULL;
			return;
		} else {
			get();
		}
		r->is_rgba = in_define_text2;
		r->StyleFlagsHasFont = ((tmp & 0x08) != 0);
		r->StyleFlagsHasColor = ((tmp & 0x04) != 0);
		r->StyleFlagsHasYOffset = ((tmp & 0x02) != 0);
		r->StyleFlagsHasXOffset = ((tmp & 0x01) != 0);
		if (r->StyleFlagsHasFont) {
			get((char*) &r->FontID, 2);
		}
		if (r->StyleFlagsHasColor) {
			if (in_define_text2) {
				get((RGBA*&) r->TextColor);
			} else {
				get((RGB*&) r->TextColor);
			}
		}
		if (r->StyleFlagsHasXOffset) {
			get((char*) &r->XOffset, 2);
		}
		if (r->StyleFlagsHasYOffset) {
			get((char*) &r->YOffset, 2);
		}
		if (r->StyleFlagsHasFont) {
			get((char*) &r->TextHeight, 2);
		}
		r->GlyphCount = get();
		//r->GlyphEntries=GlyphEntry::list_from_file(f,GlyphBits,AdvanceBits,r->GlyphCount);
		get(r->GlyphEntries, GlyphBits, AdvanceBits, r->GlyphCount);
		//throw;
	}
	void get(std::vector<GlyphEntry*>*& r, int GlyphBits, int AdvanceBits,
			int count) {
		r = new std::vector<GlyphEntry*>;
		//Bits bits;
		resetBits();
		for (int i = 0; i < count; i++) {
			GlyphEntry *rr = new GlyphEntry;
			rr->GlyphIndex = getBitsU(GlyphBits);
			rr->GlyphAdvance = getBitsS(AdvanceBits);
			//printf("GlyphIndex:%u,GlyphAdvance:%d\n",(uint)r->GlyphIndex,(int)r->GlyphAdvance);
			r->push_back(rr);
		}
	}
	void get(char*&r) {
		int size = 100;
		r = (char*) malloc(size);
		int n = 0;
		int c;
		while (1) {
			c = get();
			if (n == size) {
				r = (char*) realloc(r, size += 100);
			}
			if ((c == '\0')) {
				r[n] = '\0';
				break;
			} else {
				//cerr<<(char)c;
				r[n++] = c;
			}
		}
		//return r;
	}
	void get(DefineEditText*& r) {
		//cerr<<"DefineText2\n";
		resetBits();
		r = new DefineEditText;
		get(r->header);
		get((char*) &r->CharacterID, 2);
		get(r->Bounds);
		resetBits();
		uint16 dump;
		peek((char*) &dump, 2);
		cerr << "dumpdumpdumpdump------" << hex << dump << endl << "read:----";
		peek((char*) &dump, 2);
		cerr << "dumpdumpdumpdump------" << hex << dump << endl << "read:----";
		r->HasText = getBitsU(1);
		cerr << r->HasText;
		r->WordWrap = getBitsU(1);
		cerr << r->WordWrap;
		r->Multiline = getBitsU(1);
		cerr << r->Multiline;
		r->Password = getBitsU(1);
		cerr << r->Password;
		r->ReadOnly = getBitsU(1);
		cerr << r->ReadOnly;
		r->HasTextColor = getBitsU(1);
		cerr << r->HasTextColor;
		r->HasMaxLength = getBitsU(1);
		cerr << r->HasMaxLength;
		r->HasFont = getBitsU(1);
		cerr << r->HasFont;
		r->HasFontClass = getBitsU(1);
		cerr << r->HasFontClass;
		r->AutoSize = getBitsU(1);
		cerr << r->AutoSize;
		r->HasLayout = getBitsU(1);
		cerr << r->HasLayout;
		r->NoSelect = getBitsU(1);
		cerr << r->NoSelect;
		r->Border = getBitsU(1);
		cerr << r->Border;
		r->WasStatic = getBitsU(1);
		cerr << r->WasStatic;
		r->HTML = getBitsU(1);
		cerr << r->HTML;
		r->UseOutlines = getBitsU(1);
		cerr << r->UseOutlines << endl;
		if (r->HasFont) {
			get((char*) &r->FontID, 2);
		}
		if (r->HasFontClass) {
			get(r->FontClass);
		}
		if (r->HasFont) {
			get((char*) &r->FontHeight, 2);
		}
		if (r->HasTextColor) {
			get(r->TextColor);
		}
		if (r->HasMaxLength) {
			get((char*) &r->MaxLength, 2);
		}
		if (r->HasLayout) {
			r->Align = get();
			get((char*) &r->LeftMargin, 2);
			get((char*) &r->RightMargin, 2);
			get((char*) &r->Indent, 2);
			get((char*) &r->Leading, 2);
		}
		get(r->VariableName);
		if (r->HasText) {
			get(r->InitialText);
		}
		//		r->TextBounds->print();
//		get(r->TextMatrix);
		//		r->TextMatrix->print();
//		r->GlyphBits = get();
//		r->AdvanceBits = get();
//		get(r->TextRecords, true, r->GlyphBits, r->AdvanceBits);
//		if (get() != 0) {
//			cerr << "definetext2:Reserved must be set to 0\n";
//			exit(1);
//		}

	}
	void get(DefineText2*& r) {
		//cerr<<"DefineText2\n";
		r = new DefineText2;
		get(r->header);
		get((char*) &r->CharacterID, 2);
		get(r->TextBounds);
		//		r->TextBounds->print();
		get(r->TextMatrix);
		//		r->TextMatrix->print();
		r->GlyphBits = get();
		r->AdvanceBits = get();
		get(r->TextRecords, true, r->GlyphBits, r->AdvanceBits);
		if (get() != 0) {
			cerr << "definetext2:Reserved must be set to 0\n";
			exit(1);
		}

	}
	void get(ShapeWithStyle*& r, uint shape_version) {
		//cerr<<"ShapeWithStyle\n";
		r = new ShapeWithStyle;
		get(r->FillStyles, shape_version);
		//			r->FillStyles=FillStyleArray::from_file(f,shape_version);
		get(r->LineStyles, shape_version);
		//			r->LineStyles=LineStyleArray::from_file(f,shape_version);
		byte tmp = get();
		r->NumFillBits = ((tmp & 0xf0) >> 4);
		r->NumLineBits = (tmp & 0x0f);
		get(r->ShapeRecords, r->NumFillBits, r->NumLineBits);
		//			r->ShapeRecords=ShapeRecord::list_from_file(f,r->NumFillBits,r->NumLineBits);
		//throw;
	}
	void get(std::vector<ShapeRecord*>*& r, uint num_fill_bits,
			uint num_line_bits) {
		//cerr<<"void get(std::vector<ShapeRecord*>*& r, uint num_fill_bits,uint num_line_bits)\n";
		//throw;
		r = new std::vector<ShapeRecord*>;
		//Bits bits;
		resetBits();
		while (true) {
			uint type_flag = getBitsU(1);
			if (type_flag == 0) {
				uint tmp = getBitsU(5);
				//uint tmp=bits.read_u(5,f);
				if (tmp == 0) { //endshape
					break;
				} else { //style change
					StyleChangeRecord &s = *new StyleChangeRecord;
					s.StateNewStyles = (tmp & 0x10);
					s.StateLineStyle = (tmp & 0x8);
					s.StateFillStyle1 = (tmp & 0x4);
					s.StateFillStyle0 = (tmp & 0x2);
					s.StateMoveTo = (tmp & 0x1);
					if (s.StateMoveTo) {
						s.MoveBits = getBitsU(5);
						s.MoveDeltaX = getBitsS(s.MoveBits);
						s.MoveDeltaY = getBitsS(s.MoveBits);
					}
					if (s.StateFillStyle0) {
						s.FillStyle0 = getBitsU(num_fill_bits);
					}
					if (s.StateFillStyle1) {
						s.FillStyle1 = getBitsU(num_fill_bits);
					}
					if (s.StateLineStyle) {
						s.LineStyle = getBitsU(num_line_bits);
					}
					if (s.StateNewStyles) {
						fprintf(stderr, "unknown type_flag=%u,%u\n", type_flag,
								tmp);
						exit(17);
					}
					r->push_back(&s);
				}
			} else {
				uint tmp = getBitsU(1);
				if (tmp == 0) {
					CURVEDEDGERECORD &s = *new CURVEDEDGERECORD;
					s.NumBits = getBitsU(4);
					s.ControlDeltaX = getBitsS(s.NumBits + 2);
					s.ControlDeltaY = getBitsS(s.NumBits + 2);
					s.AnchorDeltaX = getBitsS(s.NumBits + 2);
					s.AnchorDeltaY = getBitsS(s.NumBits + 2);
					r->push_back(&s);
				} else {
					STRAIGHTEDGERECORD &s = *new STRAIGHTEDGERECORD;
					s.NumBits = getBitsU(4);
					s.GeneralLineFlag = getBitsU(1);
					if (!s.GeneralLineFlag) {
						s.VertLineFlag = getBitsU(1);
					}
					if (s.GeneralLineFlag || (!s.VertLineFlag)) {
						s.DeltaX = getBitsS(s.NumBits + 2);
					}
					if (s.GeneralLineFlag || s.VertLineFlag) {
						s.DeltaY = getBitsS(s.NumBits + 2);
					}
					r->push_back(&s);
					//				fprintf(stderr,"unknown type_flag=%u,%u\n",type_flag,tmp);
					//				exit(17);
				}
			}
		}
	}
	void get(Metadata*&r) {
		r = new Metadata;
		get(r->header);
		r->metadata = new char[r->header->length];
		//get(r->metadata,r->header->length);
		get(r->metadata);
	}
	void get(RGB*& r) {
		//cerr<<"void get(RGB*& r)\n";
		//throw;
		r = new RGB;
		r->r = get();
		r->g = get();
		r->b = get();
		//			r->print();
	}
	void get(RGBA*& r) {
		//cerr<<"void get(RGBA*& r)\n";
		r = new RGBA;
		r->r = get();
		r->g = get();
		r->b = get();
		r->a = get();
		//			throw;
	}
	void get(SetBackgroundColor*&r) {
		//cerr<<"SetBackgroundColor\n";
		//throw;
		r = new SetBackgroundColor;
		get(r->header);
		get(r->background_color); //=RGB::from_file(f);
	}
	void get(DoABC*&r) {
		r = new DoABC;
		//r->header=new TagHeader;
		//r->header=tag_header;
		get(r->header);
		//r->name=new char[1];
		//r->name[0]=0;
		get((char*) &r->flags, 4);
		get(r->name);
//		char*tmp;
//		int size=r->header->length-4-strlen(r->name)-1;
//		tmp = new char[size];
		//exit(1);
//		peek(tmp, size);
//		ofstream t("doABC");
// 		t.write(tmp,size);
//		t.close();
//		AbcFile* abcFile=new AbcFile();
		get(r->abcData);
		return;
		/*
		 r->abcData=abcFile;
		 char*p=tmp;
		 abcFile->minorVersion=*(uint16*)p;
		 p+=2;
		 abcFile->majorVersion=*(uint16*)p;
		 uint32 _r=0;
		 uint32 c;
		 int n=0;
		 while(1){
		 c=*p++;
		 _r+=(c<<7*n);
		 n++;
		 if(!(c&0x80))
		 break;
		 }
		 cerr<<_r<<endl;
		 exit(1);
		 */
	}
	void get(AbcFile*&r) {
		r = new AbcFile;
		get((char*) &r->minorVersion, 2);
		get((char*) &r->majorVersion, 2);
		cerr << r->minorVersion << endl << r->majorVersion << endl;
		get(r->constantPool);
		r->methodCount = getVIntU();
		cerr << *r->toTiXmlElement();
		for (int i = 0; i < r->methodCount; i++) {
			MethodInfo* methodInfo;
			get(methodInfo);
			r->methodInfos.push_back(methodInfo);
		}
		r->metadataCount = getVIntU();
		cerr << "metadataCount=" << r->metadataCount << endl;
		if (r->metadataCount != 0) {
			cerr << "error" << __FILE__<<dec << __LINE__<<endl;
			exit(1);
		}
		r->classCount = getVIntU();
		//cerr<<"classCount"<<classCount<<endl;
		for (int i = 0; i < r->classCount; i++) {
			Instance* instance;
			get(instance);
			r->instance.push_back(instance);
		}
		for (int i = 0; i < r->classCount; i++) {
			ClassInfo*classInfo;
			get(classInfo);
			r->classes.push_back(classInfo);
		}
		r->scriptCount = getVIntU();
		for (int i = 0; i < r->scriptCount; i++) {
			ScriptInfo*script;
			get(script);
		}
		r->methodBodyCount = getVIntU();
		for (int i = 0; i < r->methodBodyCount; i++) {
			MethodBody*methodBody;
			get(methodBody);
			r->methodBody.push_back(methodBody);
		}
		//get(r->)
		cerr << *r->toTiXmlElement() << endl;
		cerr << "end abcdata" << endl;
		//exit(1);
	}
	void get(MethodBody*&r) {
		r = new MethodBody;
		r->method = getVIntU();
		r->maxStack = getVIntU();
		r->localCount = getVIntU();
		r->initScopeDepth = getVIntU();
		r->maxScopeDepth = getVIntU();
		r->codeLength = getVIntU();
		if (r->codeLength < 0) {
			cerr << "error!" << __FILE__<<dec << __LINE__<<endl;
			exit(1);
		}
		r->code = new uint8[r->codeLength];
		get((char*) r->code, r->codeLength);
		r->exceptionCount = getVIntU();
		if (r->exceptionCount != 0) {
			cerr << "error!" << __FILE__<<dec << __LINE__<<endl;
			exit(1);
		}
		r->traitCount = getVIntU();
		if (r->traitCount != 0) {
			cerr << "error!" << __FILE__<<dec << __LINE__<<endl;
			exit(1);
		}
		for (int i = 0; i < r->traitCount; i++) {

		}
		//cerr<<*r->toTiXmlElement()<<endl;
		//exit(1);
	}
	void get(ScriptInfo*&r) {
		r = new ScriptInfo;
		r->init = getVIntU();
		r->traitCount = getVIntU();
		for (int i = 0; i < r->traitCount; i++) {
			Trait*trait;
			get(trait);
		}
	}
	void get(ClassInfo*&r) {
		r = new ClassInfo;
		r->cinit = getVIntU();
		r->traitCount = getVIntU();
		for (int i = 0; i < r->traitCount; i++) {
			Trait*trait;
			get(trait);
			r->traits.push_back(trait);
		}
	}
	void get(Trait*&r) {
		r = new Trait;
		r->name = getVIntU();
		r->kind = get();
		switch (r->kind & 0xff) {
		case 0:
		case 6:
			r->slotId = getVIntU();
			r->typeName = getVIntU();
			r->vindex = getVIntU();
			if (r->vindex != 0) {
				r->vkind = get();
			}
//			cerr<<*r->toTiXmlElement();
//			exit(1);
			break;
		case 1:
			r->dispId = getVIntU();
			r->method = getVIntU();
			break;
		case 4:
			r->slotId = getVIntU();
			r->classi = getVIntU();
			break;
		default:
			cerr << "err:unknown kind" << (r->kind & 0xff) << "at"
					<< __FILE__<<dec << __LINE__<<endl;
			exit(1);
		}
		if (((r->kind & 0xff00) >> 4) & 0x4) { //has metadata
			cerr << "err" << __FILE__<<dec << __LINE__<<endl;
			exit(1);
			r->metadataCount = getVIntU();
		}
		cerr << *r->toTiXmlElement();
		//exit(1);
	}
	void get(Instance*&r) {
		r = new Instance;
		r->name = getVIntU();
		r->superName = getVIntU();
		r->flags = get();
		if (r->flags & 8) {
			r->protectedNs = getVIntU();
			//cerr<<"error"<<__FILE__<<dec<<__LINE__<<endl;
			//exit(1);
		}
		r->interfaceCount = getVIntU();
		if (r->interfaceCount != 0) {
			cerr << "error" << __FILE__<<dec << __LINE__<<endl;
			exit(1);
		}
		r->iinit = getVIntU();
		r->traitCount = getVIntU();
		for (int i = 0; i < r->traitCount; i++) {
			Trait* trait;
			get(trait);
			r->trait.push_back(trait);
		}
		/*
		 if(r->flags&1){
		 cerr<<"error"<<__FILE__<<dec<<__LINE__<<endl;
		 exit(1);
		 }
		 if(r->flags&2){
		 cerr<<"error"<<__FILE__<<dec<<__LINE__<<endl;
		 exit(1);
		 }
		 if(r->flags&4){
		 cerr<<"error"<<__FILE__<<dec<<__LINE__<<endl;
		 exit(1);
		 }
		 */
		//cerr<<*r->toTiXmlElement()<<endl;
		//exit(1);
	}
	void get(OptionInfo*&r) {
		r = new OptionInfo;
		r->optionCount = getVIntU();
		for (int i = 0; i < r->optionCount; i++) {
			OptionDetail* detail;
			get(detail);
			r->option.push_back(detail);
		}
		cerr << "optioncount:" << r->optionCount << endl;
		//cerr<<"errer"<<dec<<__FILE__<<__LINE__<<endl;
		//exit(1);
	}
	void get(OptionDetail*&r) {
		r = new OptionDetail;
		r->val = getVIntU();
		r->kind = get();
		//cerr<<"errer"<<__FILE__<<dec<<__LINE__<<endl;
		//exit(1);
	}
	void get(MethodInfo*&r) {
		r = new MethodInfo;
		r->paramCount = getVIntU();
		r->returnType = getVIntU();
		cerr << "count:" << r->paramCount << ":type:" << r->returnType << endl;
		for (int i = 0; i < r->paramCount; i++) {
			r->paramType.push_back(getVIntU());
		}
		r->name = getVIntU();
		r->flags = get();
		cerr << "name:" << r->name << ":flags:" << (uint32) r->flags << endl;
		if (r->flags & 0x08) {
			get(r->options);
		}
		if (r->flags & 0x80) { //has param names
			cerr << "errer" << __FILE__<<__LINE__<<endl;
			exit(1);
		}
		//exit(1);
		cerr << "method end" << endl;
	}
	uint32 getVIntU() {
		uint32 r = 0;
		uint32 c;
		int n = 0;
		while (1) {
			if (n == 5)
				exit(2);
			c = get();
			r += ((c & 0x7f) << (7 * n));
			//r<<=7;
			//r+=(c&0x7f);
			n++;
			cerr << endl << n << ":" << hex << c << " ";
			if (!(c & 0x80))
				break;
		}
		return r;
	}
	void get(Namespace *&r) {
		r = new Namespace;
		r->kind = get();
		r->name = getVIntU();
	}
	void get(NamespaceSet *&r) {
		r = new NamespaceSet;
		r->count = getVIntU();
		for (int i = 0; i < r->count; i++) {
			r->namespaces.push_back(getVIntU());
		}
	}
	void get(MultinameInfo*& r) {
		//r=new MultinameInfo;
		uint8 kind = peek();
		cerr << "kind:" << (uint32) kind << endl;
		switch (kind) {
		case 7:
			//r=new QName;
			get((QName*&) r);
			break;
		case 9:
			get((Multiname*&) r);
			break;
		case 0x1b:
			get((MultinameL*&) r);
			break;
		case 0x11:
			get();
			break;
		default:
			cerr << "unknown multiname kind" << endl;
			exit(1);
		}
	}
	void get(QName*&r) {
		r = new QName;
		r->kind = get();
		r->ns = getVIntU();
		r->name = getVIntU();
	}
	void get(MultinameL*&r) {
		r = new MultinameL;
		r->kind = get();
		//r->name=getVIntU();
		r->namespaceSet = getVIntU();
	}
	void get(Multiname*&r) {
		r = new Multiname;
		r->kind = get();
		r->name = getVIntU();
		r->namespaceSet = getVIntU();
	}
	void get(ConstantPool*& r) {
		r = new ConstantPool;
		r->intCount = getVIntU();
		cerr << *r->toTiXmlElement() << endl;
		for (int i = 0; i + 1 < r->intCount; i++) {
			r->integers.push_back(getVIntU());
		}
		r->uintCount = getVIntU();
		cerr << *r->toTiXmlElement() << endl;
		//exit(1);
		for (int i = 0; i + 1 < r->uintCount; i++) {
			r->uintegers.push_back(getVIntU());
		}
		r->doubleCount = getVIntU();
		cerr << *r->toTiXmlElement() << endl;
		//exit(1);
		for (int i = 0; i + 1 < r->doubleCount; i++) {
			double tmp;
			get((char*) &tmp, 8);
			r->doubles.push_back(tmp);
		}
		r->stringCount = getVIntU();
		cerr << *r->toTiXmlElement() << endl;
		//exit(1);
		for (int i = 0; i + 1 < r->stringCount; i++) {
			cerr << "i=" << i << endl;
			StringInfo* string;
			get(string);
			r->strings.push_back(string);
			//cerr<<*string->toTiXmlElement()<<endl;
			//cerr<<string->utf8<<endl;
			std::stringstream ss;
			ss << i << ".txt";
			//ofstream o(ss.str().c_str());
			//o << string->utf8;
			//o<<*string->toTiXmlElement();
			//o.close();
		}
		r->namespaceCount = getVIntU();
		cerr << *r->toTiXmlElement() << endl;
		//exit(1);
		for (int i = 0; i + 1 < r->namespaceCount; i++) {
			cerr << "i=" << i << endl;
			Namespace* ns;
			get(ns);
			r->namespaces.push_back(ns);
			//cerr<<*string->toTiXmlElement()<<endl;
			//cerr<<string->utf8<<endl;
		}
		r->namespaceSetCount = getVIntU();
		for (int i = 0; i + 1 < r->namespaceSetCount; i++) {
			cerr << "i=" << i << endl;
			NamespaceSet* ns;
			get(ns);
			r->namespaceSets.push_back(ns);
			//cerr<<*string->toTiXmlElement()<<endl;
			//cerr<<string->utf8<<endl;
		}
		r->multinameCount = getVIntU();
		for (int i = 0; i + 1 < r->multinameCount; i++) {
			cerr << "multiname i=" << i << endl;
			MultinameInfo *mul;
			get(mul);
			r->multinames.push_back(mul);
			//cerr<<*string->toTiXmlElement()<<endl;
			//cerr<<string->utf8<<endl;
		}
		cerr << *r->toTiXmlElement() << endl;
		ofstream p("pool.xml");
		p << *r->toTiXmlElement();
		p.close();
		cerr << "end constant pool";
		//exit(1);
		//cerr<<sizeof(double)<<endl;
	}
	void get(StringInfo*& r) {
		r = new StringInfo;
		r->size = getVIntU();
		cerr << "size=" << dec << r->size << endl;
		r->utf8 = new char[r->size + 1];for
(		int i=0;i<r->size;i++) {
			r->utf8[i]=get();
		}
		r->utf8[r->size] = 0;
	}
	void get(Tag*& r) {
		//cerr<<"void get(Tag*& r)\n";
		//throw;
		r = new Tag;
		TagHeader *tag_header = NULL;
		peek(tag_header);
		//cerr<<"tag_header="<<endl;
		tag_header->print();
		byte* tmp = new byte[tag_header->length];
		if (tag_header->type == 0) { //done
			std::cerr << ("end tag,file ends\n");
			r = NULL;
		} else if (tag_header->type == 1) { //done
			r = new ShowFrame;
			get(r->header);
			r->header->print();
			char*tmp;
			tmp = new char[r->header->length];
			get(tmp, r->header->length);
			//delete tmp;
			std::cerr << "ShowFrame,no more info,exit";
			//exit(2);
		} else if (tag_header->type == 9) { //done
			std::clog << "set background color";
			SetBackgroundColor *r1;
			get(r1);
			r = r1;
//		} else if (tag_header->type == 26) { //ok
			//		std::clog << "PlaceObject2\n";
			//	PlaceObject2* r1;
			//get(r1);
			//	r = r1;
//		} else if (tag_header->type == 32) { //ok
//			DefineShape3* r1;
			//		get(r1);
			//	r = r1;
		} else if (tag_header->type == 37) {
			DefineEditText* r1;
			get(r1);
			r = r1;
		} else if (tag_header->type == 69) { //ok
			FileAttributes* r1 = NULL;
			get(r1);
			r = r1;
		} else if (tag_header->type == 33) { //done?
			DefineText2* r1;
			get(r1);
			r = r1;
		} else if (tag_header->type == 48) { //done?
			DefineFont2* r1;
			get(r1);
			r = r1;
		} else if (tag_header->type == 77) { //metadata
			Metadata* r1;
			get(r1);
			r = r1;
		} else if (tag_header->type == 74) { //done,not care?
			CSMTextSettings* r1;
			get(r1);
			r = r1;
		} else if (tag_header->type == 82) { //doABC
			DoABC* r1;
			get(r1);
			r = r1;
//		} else if (tag_header->type == TAG_TYPE_DEFINE_SHAPE) { //done
//			DefineShape* r1;
			//		get(r1);
			//	r = r1;
		} else if (tag_header->type == TAG_TYPE_DEFINE_BITS_LOSSLESS) {
			DefineBitsLossless* r1;
			get(r1);
			r = r1;
		} else {
			std::cerr << "unknown tag type:" << (uint) tag_header->type << "\n";
			r = new Tag;
			//r->header=new TagHeader;
			//r->header=tag_header;
			get(r->header);
			char*tmp;
			tmp = new char[r->header->length];
			//exit(1);
			get(tmp, r->header->length);
			//delete tmp;
		}
		//delete tmp;
		cerr << "void get(Tag*& r) ends\n";
	}
	SWFInputStream(std::ifstream* i) {
		//cerr<<"4444444444444444444444444";
		//exit(1);
		bytes_read = 0;
		is = i;
		buf_size = 10;
		buf = new byte[buf_size];
		buf_bytes = 0;
		resetBits();
	}
private:
	void resetBits() {
		offset = 0;
		nbytes = 0;
		bits_num = 0;
	}
	void get(Rect *& r) {
		resetBits();
		r = new Rect;
		r->n_bits = getBitsU(5);
		r->x_min = getBitsS(r->n_bits);
		r->x_max = getBitsS(r->n_bits);
		r->y_min = getBitsS(r->n_bits);
		r->y_max = getBitsS(r->n_bits);
		//return r;
	}
	unsigned char get() {
		unsigned char r;
		get((char*) &r, 1);
		return r;
		//cerr<<"char get()\n";
		//throw;
		//return is->get();
	}
	uint getBitsU(uint n) {
		//cerr<<"uint getBitsU("<<n<<"),offset="<<offset<<",byte="<<byte_data<<endl;
		if (n > 32) {
			std::cerr << "too long bits\n";
			exit(1);
		}
		bits_num += n;
		uint32 r;
		if (offset > 0) { //n is data
			r = byte_data & (((unsigned char) 0xff) >> offset);
			if (n + offset <= 8) {
				r >>= (8 - offset - n);
				offset += n;
				if (offset == 8) {
					offset = 0;
				}
				//cerr<<"bits1!!"<<r<<endl;
				//cerr<<"uint getBitsU("<<n<<") return at mid,offset="<<offset<<",byte="<<byte_data<<endl;
				return r;
			} else {
				n -= 8 - offset;
			}
		} else {
			r = 0;
		}
		byte_data = get();
		//	puts("!!!!!!!byte");
		while (n > 8) {
			n -= 8;
			//		r*=256;
			r <<= 8;
			r += byte_data;
			byte_data = get();
			nbytes++;
			//		puts("!!!!!!!byte");
		}
		byte tmp = byte_data & (((unsigned char) 0xff) << (8 - n));
		tmp >>= (8 - n);
		r <<= n;
		r += tmp;
		offset = n;
		if (offset == 8) {
			offset = 0;
		}
		//cerr<<"bits2!!"<<r<<endl;
		//cerr<<"uint getBitsU("<<n<<") ends,offset="<<offset<<",byte="<<byte_data<<endl;
		return r;
	}
	int32 getBitsS(uint n) {
		uint32 r = getBitsU(n);
		if ((r >> (n - 1)) != 0) { // r<0
			r |= (((uint) (-1)) << n);
		}
		return *((int32*) &r);
	}
	void get(char* _buf, size_t size) {
		//cerr<<"void get(char*& buf,size_t size),size="<<size<<"\n";
		//			throw;
		peek(_buf, size);
		buf_bytes -= size;
		bytes_read += size;
		memmove(this->buf, this->buf + size, buf_bytes);
	}
	size_t peek(TagHeader*& r) {
		//cerr<<"void peek(TagHeader*&)\n";
		size_t byte_num = 0;
		//			throw;
		r = new TagHeader;
		//uint16 tmp;
		char tmp[100];
		peek(tmp, 2);
		byte_num = 2;
		r->type = ((*(uint16*) tmp) & 0xffc0) >> 6;
		r->length = (*(uint16*) tmp) & 0x3f;
		if (r->length == 63) {
			peek(tmp, 6);
			uint32 tmp2;
			peek((char*) &tmp2, 4);
			byte_num = 6;
			//				if(feof(f)){
			//					return NULL;
			//				}
			r->length = *(uint32*) (tmp + 2); //tmp2;
		}
		return byte_num;
	}
	uint8 peek() {
		uint8 r;
		peek((char*) &r, 1);
		return r;
	}
	void peek(char*dest, size_t size) {
		//	cerr<<"void peek(char *dest="<<(void*)dest<<",size_t size="<<size<<")\n";
		//	cerr<<"---buf="<<(void*)buf<<",buf_size="<<buf_size<<",buf_bytes="<<buf_bytes<<endl;
		//throw;
		//			char *p=dest;
		if (buf_bytes < size) {
			if (buf_size < size) {
				buf_size = size;
				byte *tmp = new byte[buf_size];
				memcpy(tmp, buf, buf_bytes);
				//delete buf;
				buf = tmp;
			}
			while (buf_bytes < size) {
				buf[buf_bytes++] = is->get();
			}
		}
		memcpy(dest, buf, size);
	}
	void get(TagHeader*& header) {
		//cerr<<"void get(TagHeader*& header)"<<endl;
		char*buf = new char[peek(header)];get(buf,peek(header));
		return;
	}
	bool eof() {
		return is->eof();
	}
public: int bytes_read;
private:
	std::ifstream* is;
	/////////////////////////
				int offset;
				int nbytes;
				int bits_num;
				byte byte_data;
	///////////////////////////
				size_t buf_size;
				byte *buf;
				size_t buf_bytes;
			};}
#endif
